<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<div id="map"></div>
<div id="popup" class="ol-popup">
    <a href="#" id="popup-closer" class="ol-popup-closer"></a>
    <div id="popup-title" class="popup-title"></div>
    <div id="popup-content" class="popup-content"></div>
</div>

<script>
    //设置总数，生成集合
    var count = 2000;
    var features = new Array(count);
    var e = 450000;
    for (var i = 0; i < count; ++i) {
        var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
//添加矢量元素
        features[i] = new ol.Feature(new ol.geom.Point(coordinates));
    }
    //矢量图层源  源是用于获取映射块的协议【必须】
    var source = new ol.source.Vector({
        features: features,
        // 图层元素 【必须】
    });

    //聚合
    var clusterSource = new ol.source.Cluster({
        distance: 100,     //群集之间的最小距离（以像素为单位）。
        source: source,	   //数据源
    });

    var styleCache = {};
    var clusters = new ol.layer.Vector({
        //图层类型
        source: clusterSource,
        style: function (feature) {
            //样式
            var size = feature.get('features').length;
            var style = styleCache[size];
            if (!style) {
                style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        stroke: new ol.style.Stroke({
                            color: '#fff',
                        }),
                        fill: new ol.style.Fill({
                            color: '#3399CC',
                        }),
                    }),
                    text: new ol.style.Text({
                        text: size.toString(),
                        fill: new ol.style.Fill({
                            color: '#fff',
                        }),
                    }),
                });
                styleCache[size] = style;
            }
            return style;
        },
    });

    var raster = new ol.layer.Tile({
        //平铺图层
        source: new ol.source.OSM(),
        //图层源 定义图层映射协议
    });

    var map = new ol.Map({
        layers: [raster, clusters],
        //图层
        target: 'map',
        view: new ol.View({
            //视图
            center: [0, 0],
            zoom: 2,
        }),
        interactions: ol.interaction.defaults({
            doubleClickZoom: false,
            // 取消双击放大功能交互
        }),
    });

    // 点击地图展示弹窗
    const popup = new ol.Overlay({
        element: document.getElementById('popup'),
        positioning: 'bottom-center',
        //相对于其位置属性的实际位置
        stopEvent: false,
        //事件冒泡
    });
    map.addOverlay(popup);
    map.on('singleclick', evt => {
        clickMap(evt);
    });

    //点击事件
    function clickMap(evt) {
        feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layerVetor) { return feature; });
        if (feature) {
            console.log('聚合')
            if (feature.getProperties().features) { //聚合情况下
                if (feature.getProperties().features.length == 1) {
                    let element = popup.getElement();       // 获取弹窗的DOM元素
                    var coordinate = evt.coordinate;		//当前位置信息
                    console.log(coordinate)
                    popup.setPosition(coordinate); 			//设置当前位置
                    featuerInfo = feature.getProperties().features[0].N.geometry.A;
// featuerInfo = feature.getProperties().features[0].N.attribute;
                    element.innerHTML = '<code>' + coordinate[0] + '</code>';	//弹窗内容

// addFeatrueInfo(featuerInfo); //在popup中加载当前要素的具体信息
                    if (popup.getPosition() == undefined) {
                        popup.setPosition(coordinate);
                    }
                } else {
                    //有多个要素
                    console.log('多个聚合')
                    popup.setPosition(undefined);
                }
            } else {
                popup.setPosition(undefined);
            }
        } else {
            console.log('非聚合')
            popup.setPosition(undefined);
        }
    }
</script>

</body>
</html>